/**
 * 纹理管理类-生成纹理，保存纹理，对纹理统一管理
 * @date   2011-3-21
 * @author tianye
 */
package cn.edu.dlut.WingGame.Graphic;

import java.io.InputStream;
import java.util.ArrayList;

import javax.microedition.khronos.opengles.GL10;

import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Bitmap.Config;
import android.graphics.drawable.BitmapDrawable;
import android.opengl.GLUtils;

public class GLTexContainer {
	private static int mTexCount = 0;// 当前纹理数目
	private static ArrayList<GLTexData> mTextures = new ArrayList<GLTexData>();// 所有纹理数据

	// 生成纹理
	public static synchronized void creatTexture(int ResourceID, GLTexture tex) {
		GLTexData data;
		for (int i = 0; i < mTexCount; i++) {
			data = mTextures.get(i);
			if (data.mResourceID == ResourceID && data.isBind
					&& data.isKeyColor == tex.mData.isKeyColor) {
				if ((!data.isKeyColor)
						|| (data.isKeyColor && data.keyColor.getColor() == tex.mData.keyColor
								.getColor())) {
					tex.mData = data;
					return;
				}
			}
		}
		Bitmap image = null;
		try {
			BitmapDrawable bd = (BitmapDrawable) GLDevice.getActivity()
					.getResources().getDrawable(ResourceID);
			image = bd.getBitmap();
		} catch (Exception e) {

		}
		Bitmap bitmap = creatBitmap(image, tex.mData);
		image.recycle();
		image = null;
		creatTexture(bitmap, tex.mData);
		bitmap.recycle();
		bitmap = null;
	}

	public static synchronized void creatTexture(String Path, GLTexture tex) {
		GLTexData data;
		for (int i = 0; i < mTexCount; i++) {
			data = mTextures.get(i);
			if (data.mPath == Path && data.isBind
					&& data.isKeyColor == tex.mData.isKeyColor) {
				if ((!data.isKeyColor)
						|| (data.isKeyColor && data.keyColor.getColor() == tex.mData.keyColor
								.getColor())) {
					tex.mData = data;
					return;
				}
			}
		}
		Bitmap image = null;
		try {
			AssetManager am = GLDevice.getActivity().getAssets();
			InputStream is = am.open(Path);
			image = BitmapFactory.decodeStream(is);
			is.close();

		} catch (Exception e) {

		}
		Bitmap bitmap = creatBitmap(image, tex.mData);
		image.recycle();
		image = null;
		creatTexture(bitmap, tex.mData);
		bitmap.recycle();
		bitmap = null;
	}

	public static synchronized void creatTexture(Bitmap bmp, GLTexData data) {

		int[] textures = new int[1];
		GLDevice.getGL().glGenTextures(1, textures, 0);
		data.mTextureID = textures[0];

		GLDevice.getGL().glBindTexture(GL10.GL_TEXTURE_2D, data.mTextureID);

		if (GLDevice.isLowQuality) {
			GLDevice.getGL().glTexParameterf(GL10.GL_TEXTURE_2D,
					GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
			GLDevice.getGL().glTexParameterf(GL10.GL_TEXTURE_2D,
					GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_NEAREST);
		} else { // 使用【GL10.GL_NEAREST】可以提高效率 但图片缩放时质量很差
			GLDevice.getGL().glTexParameterf(GL10.GL_TEXTURE_2D,
					GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
			GLDevice.getGL().glTexParameterf(GL10.GL_TEXTURE_2D,
					GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
		}
		GLDevice.getGL().glTexParameterf(GL10.GL_TEXTURE_2D,
				GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);
		GLDevice.getGL().glTexParameterf(GL10.GL_TEXTURE_2D,
				GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);

		// GLDevice.getGL().glTexEnvf(GL10.GL_TEXTURE_ENV,
		// GL10.GL_TEXTURE_ENV_MODE,GL10.GL_REPLACE);
		// GLDevice.getGL().glTexEnvf(GL10.GL_TEXTURE_ENV,
		// GL10.GL_TEXTURE_ENV_MODE,GL10.GL_BLEND);
		GLDevice.getGL().glTexEnvf(GL10.GL_TEXTURE_ENV,
				GL10.GL_TEXTURE_ENV_MODE, GL10.GL_MODULATE);

		GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmp, 0);

		mTexCount++;
		mTextures.add(data);
	}

	// 清除keycolor
	public static void setKeycolor(Bitmap bmp, GLTexData data) {
		int tcolor;
		for (int i = 0; i < bmp.getWidth(); i++)
			for (int j = 0; j < bmp.getHeight(); j++) {
				tcolor = bmp.getPixel(i, j);
				if (tcolor == data.keyColor.getColor()) {
					bmp.setPixel(i, j, 0x00000000);
				}
			}
	}

	public static synchronized Bitmap creatBitmap(Bitmap bmp, GLTexData data) {
		data.mWidth = bmp.getWidth();
		data.mHeight = bmp.getHeight();

		data.mPow2Height = pow2(data.mHeight);
		data.mPow2Width = pow2(data.mWidth);
		Config bmpconfig;
		if (bmp.hasAlpha() || data.isKeyColor)
			bmpconfig = Bitmap.Config.ARGB_8888;
		else
			bmpconfig = Bitmap.Config.RGB_565;

		Bitmap bitmap = Bitmap.createBitmap(data.mPow2Width, data.mPow2Height,
				bmpconfig);
		Canvas canvas = new Canvas(bitmap);
		canvas.drawBitmap(bmp, 0, 0, null);
		bmp = null;

		if (data.isKeyColor)
			setKeycolor(bitmap, data);
		data.isAlpha = bitmap.hasAlpha();
		return bitmap;
	}

	// 转换成2^n
	public static int pow2(int size) {
		int small = (int) (Math.log(size) / Math.log(2.0f));
		if ((1 << small) >= size)
			return 1 << small;
		else
			return 1 << (small + 1);
	}

	// 删除纹理
	public static synchronized boolean deleteTexture(int mTextureID) {
		boolean isFind = false;

		for (int i = 0; i < mTexCount; i++) {
			if (mTextures.get(i).mTextureID == mTextureID) {
				mTextures.remove(i);
				mTexCount--;
				isFind = true;
				break;
			}

		}
		if (isFind && mTextureID != -1) {
			GLDevice.getGL().glDeleteTextures(1, new int[] { mTextureID }, 0);
			mTextureID = -1;
			return true;
		}
		return false;
	}

	public static synchronized boolean rebindTexture() {
		for (; mTexCount > 0;) {
			mTextures.get(0).isBind = false;
			GLDevice.getGL().glDeleteTextures(1,
					new int[] { mTextures.get(0).mTextureID }, 0);
			mTextures.remove(0);
			mTexCount--;
		}
		mTexCount = 0;
		return false;
	}

}
